package com.stropheware.pathfinding;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.ListIterator;

import android.util.Log;

import com.stropheware.droidDefense.AbstractTower;
import com.stropheware.droidDefense.Cell;
import com.stropheware.droidDefense.GameBoard;

public class UnionFind {
	
	private ArrayList<TowerSet> towerSets;
	private GameBoard gameBoard;
	private final static String TAG = "UnionFind";
	private int addToOtherSide;
	
	private int startX, startY, endX, endY;
	
	public UnionFind(GameBoard gameBoard) {
		this.gameBoard = gameBoard;
		towerSets = new ArrayList<TowerSet>();
		addToOtherSide = 2 * gameBoard.MINIMUM_MONSTER_PATH + AbstractTower.TOWER_SIDE_LENGTH;
	}
	
	private void setStartEndValues(Cell topLeftCell) {
		startX = topLeftCell.column - gameBoard.MINIMUM_MONSTER_PATH;
		endX = startX + addToOtherSide;
		if(startX < 0) startX = 0;
		if(endX > gameBoard.numCellsWide - 1) endX = gameBoard.numCellsWide - 1;
		startY = topLeftCell.row - gameBoard.MINIMUM_MONSTER_PATH;
		endY = startY + addToOtherSide;
		if(startY < 0) startY = 0;
		if(endY > gameBoard.numCellsHeight - 1) endY = gameBoard.numCellsHeight - 1;
		//Log.d(TAG, "startX:" + startX);
		//Log.d(TAG, "endX:" + endX);
		//Log.d(TAG, "startY:" + startY);
		//Log.d(TAG, "endY:" + endY);
	}
	
	public boolean isValidPlacement(Cell topLeftCell) {
		setStartEndValues(topLeftCell);
		boolean gHasTopEdge = gameBoard.hasTopEdgeTower(topLeftCell.column, topLeftCell.row);
		boolean gHasBottomEdge = gameBoard.hasBottomEdgeTower(topLeftCell.column, topLeftCell.row);
		for(int x = startX; x < endX; x++) {
			for(int y = startY; y < endY; y++) {
				Cell tempCell = gameBoard.cellGrid[x][y];
				if(tempCell.content == Cell.TOWER) {
					TowerSet currentTowerSet = tempCell.occupiedTower.currentTowerSet;
					if(currentTowerSet.hasTopEdge) gHasTopEdge = true;
					if(currentTowerSet.hasBottomEdge) gHasBottomEdge = true;
					if(gHasTopEdge && gHasBottomEdge) return false;
				}
			}
		}
		return true;
	}
	
	public void addTower(AbstractTower addTower) {
		TowerSet newTowerSet = new TowerSet();
		towerSets.add(newTowerSet);
		newTowerSet.addTower(addTower);
		setStartEndValues(addTower.cellsOccupied[0][0]);
		for(int x = startX; x < endX; x++) {
			for(int y = startY; y < endY; y++) {
				Cell tempCell = gameBoard.cellGrid[x][y];
				if(tempCell.content == Cell.TOWER) {
					TowerSet currentTowerSet = tempCell.occupiedTower.currentTowerSet;
					if(!currentTowerSet.equals(newTowerSet)) {
						newTowerSet.addTowerSet(currentTowerSet);
						towerSets.remove(currentTowerSet);
					}
				}
			}
		}
		Log.d(TAG, "number of tower sets = " + towerSets.size());
	}
	
	public void removeTower(AbstractTower removeTower) {
		TowerSet oldSet = removeTower.currentTowerSet;
		oldSet.towerList.remove(removeTower);
		for(int i = 0; i < oldSet.towerList.size(); i++) {
			addTower(oldSet.towerList.get(i));
		}
		towerSets.remove(oldSet);
	}
}
